const zlib = require('zlib');
const { Buffer } = require('buffer');
const vm = require('vm');
const crypto = require('crypto')



const axios = require('axios');

const instance = axios.create({
  withCredentials: true, // 允许携带跨域凭证
  timeout: 500000,
  headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 daodan/test.0.0.1' }
});

async function request(method, url, params, data, headers, timeout) {
  return instance.request({
    method,
    url,
    params,
    data,
    headers,
    timeout
  })

}


var fixed = 1;
function getID(key) {
  if (!key) {
    key = "";
  }
  const timestamp = new Date().getTime();
  const randomNumber = Math.floor(Math.random() * 90) + 1;
  const id = key + "_" + fixed + randomNumber + "_" + timestamp;
  fixed++;
  return id;
}

function decompressBase64String(base64String) {
  return new Promise((resolve, reject) => {
    try {
      // 将Base64字符串转换为字节数组  
      const base64Buffer = Buffer.from(base64String, 'base64');

      // 解压缩字节数组  
      zlib.gunzip(base64Buffer, (err, data) => {
        if (err) {
          reject(err)
          return
        }
        resolve(data.toString())
      });
    } catch (err) {
      console.error('解压缩时发生错误:', err);
      reject(err)
    }
  })

}


function run(params, req,res, code) {
  // 创建一个沙箱对象，并添加一个 console 对象用于捕获 console.log 的输出  
  const sandbox = {
    printInfo: [],
    console: {
      log: function (...message) {
        console.log('console.log:', ...message); // 打印 console.log 的输出  
        sandbox.printInfo.push(...message)
      },
      error: function (...message) {
        console.log('console.log:', ...message); // 打印 console.log 的输出  
        sandbox.printInfo.push(...message)
      }
    },
    print: (...m) => {
      console.log('console.log:', ...m); // 打印 console.log 的输出  
      sandbox.printInfo.push(...m)
    },
    request: { ...req },
    params: { ...params },
    response:{...res},
    stopVal:{
      flag:false,
      reason:'',
    },
    stop: function (reason) {
      sandbox.stopVal.flag = true;
      sandbox.stopVal.reason = reason;
    },
    tool: {
      md5: function (content) {
        const md5 = crypto.createHash('md5')
        return md5.update(content).digest('hex')
      },
      base64Encode: function (str) {
        const buff = Buffer.from(str, 'utf-8');
        return buff.toString('base64');
      },
      base64Decode: function (encodedStr) {
        const buff = Buffer.from(encodedStr, 'base64');
        return buff.toString('utf-8');
      },
      timestamp: function (notms) {
        let t = new Date().getTime()
        if (notms) {
          t = t / 1000
        }
        return Math.floor(t)
      },
      hmac: function (key, da) {
        // 创建一个hmac对象
        const hmac = crypto.createHmac('md5', key);
        // 往hmac对象中添加摘要内容
        const up = hmac.update(da);
        // 使用 digest 方法输出摘要内容
        return up.digest('hex');
      },
      aes_cbc_encode: function (key, iv, da, wei) {
        let algorithm = 'aes-256-cbc'
        if (wei) {
          algorithm = `aes-${wei}-cbc`
        }
        const cipher = crypto.createCipheriv(algorithm, Buffer.from(key, 'hex'), Buffer.from(iv, 'hex'));
        let cText = cipher.update(da, "utf-8", "hex");
        cText += cipher.final("hex");
        return cText
      }, aes_cbc_decode: function (key, iv, da, wei) {
        let algorithm = 'aes-256-cbc';
        if (wei) {
          algorithm = `aes-${wei}-cbc`;
        }
        const decipher = crypto.createDecipheriv(algorithm, key, iv);
        let dText = decipher.update(cText, "hex", "utf-8");
        dText += decipher.final("utf8");
        return dText;
      },
      randomNumber: function (min, max) {
        let di = min;
        let jian = max - min;
        if (max <= min) {
          di = max;
          jian = (-1) * jian
        }
        return Math.floor(Math.random() * jian + di);
      },
      randomlength: function (length) {
        return crypto.randomBytes(length).toString('hex');
      }
    }
  };
  // 在沙箱中执行代码  
  vm.createContext(sandbox); // 创建上下文环境  
  let data={error:''}
  try {
    vm.runInContext(code, sandbox)
  } catch (err) {

    let line = err.stack.split('\n')
    let line_res = ['Error executing code:']
    for (var i = 0; i < line.length; i++) {
      if (line[i].startsWith('	at')) {
        continue
      }
      line_res.push('    ' + line[i])
    }
    data.error = line_res.join('\n')
  }
  data.request = sandbox.request;
  data.response = sandbox.response;
  data.printInfo = sandbox.printInfo;
  data.stop = {flag:sandbox.stopVal.flag,reason:sandbox.stopVal.reason}
  return data;
}




module.exports = {
  getID,
  decompressBase64String,
  run,
  request
};
